/*
** ############################################################################
**     Project   : osdee - Operative Systems Design for Embedded Envrionments
**     File      : SchM.c
**     Revision  ; 1.0
**     Abstract  :
**         Scheduler Module implementation.
**
**     Copyright : 2014 Fernando Rodriguez - Victor Huidobro, 
**                 Open source with out any responsability.
**     
**     mail      : frr@gmail.com, vhuidobrog@gmail.com
** ############################################################################
*/

#include "SchM.h"
#include <MC9S12XEP100.h>


/*
** ============================================================================
**     Global Variables
** ============================================================================
*/
BOOL m_boStop;                          /* Flag to stop scheduler, if DeInit is called  */
UINT16 m_tSchm_Counter;                 /* Binary Progressive Schedule Counter          */
const tsOS_Des_Cfg* m_pTasksDescriptor; /* Reference to Configured Tasks Descriptor     */
BOOL                boPendingActivation;/* Indicates BPS Activation pending due Busy TCM*/

/*
** ============================================================================
**     Declaration of internal functions (Not exposed in the Schm API)
** ============================================================================
*/
void vUpdateErrorStatus(teE_OS_ERR tError);
void vBinaryProgressiveTaskActivation(void);
void vSetBackgroundTaskLogBit(BOOL boNewStatus);

/*
** ============================================================================
**     Implementation of API exposed functions
** ============================================================================
*/

/*
** ============================================================================
**     Function    :  SchM_Init
**
**     Description :
**         Initializes the Scheduler module with an specified Configuration.
** ============================================================================
*/
void SchM_Init(const tsOS_Des_Cfg* ptOS_Cfg)
{
  m_boStop = FALSE;
  m_tSchm_Counter = 0xFFFF;
  m_pTasksDescriptor = ptOS_Cfg;
  boPendingActivation = FALSE;
  
  //OS_Init(ptOS_Cfg);
}

/*
** ============================================================================
**     Function    :  SchM_DeInit
**
**     Description :
**         Deinitializes the Scheduler module.
** ============================================================================
*/
void SchM_DeInit(void)
{
  Gpt_DisableNotification(PIT0);
  m_boStop = TRUE;	
}

/*
** ============================================================================
**     Function    :  SchM_Start
**
**     Description :
**         Starts the Scheduler operation.
** ============================================================================
*/
void SchM_Start(void)
{
  m_boStop = FALSE;
  Gpt_EnableNotification(PIT0);  
//  SchM_Background();
}

/*
** ============================================================================
**     Function    :  SchM_OsTick
**
**     Description :
**         OS Tick Callback provided by the Scheduler.
** ============================================================================
*/
void SchM_OsTick(void)
{
  vSetBackgroundTaskLogBit(TRUE);    
  
  vBinaryProgressiveTaskActivation();
    
  vSetBackgroundTaskLogBit(FALSE);
}

/*
** ============================================================================
**     Function    :  SchM_Background
**
**     Description :
**         Scheduler Background Task.
** ============================================================================
*/
void SchM_Background(void)
{
  while(!m_boStop)
  {
    vSetBackgroundTaskLogBit(TRUE);
    if(boPendingActivation)
    {
      vBinaryProgressiveTaskActivation();
    }
    
   // vDispatcher();      
  }
}


/*
** ============================================================================
**     Implementation of internal functions
** ============================================================================
*/

/*
** ============================================================================
**     Function    :  vSetBackgroundTaskLogBit
**
**     Description :
**         Update Backgroundtask Log bit status.
**     Parameter   : 
**         -boEnable: New status: TRUE > On, FALSE > Off.
** ============================================================================
*/
void vSetBackgroundTaskLogBit(BOOL boNewStatus)
{
  if(boNewStatus)
  {
    PORTB_PB0 = 1u;   /* Set Background task log bit */
  }
  else
  {
    PORTB_PB0 = 0;   /* Clear Background task log bit */
  }
}

/*
** ============================================================================
**     Function    :  vUpdateErrorStatus
**
**     Description :
**         Update Backgroundtask Log bit status.
**     Parameter   : 
**         -teSCHM_ERROR: Error status.
** ============================================================================
*/
void vUpdateErrorStatus(teE_OS_ERR tError)
{
  switch(tError)
  {
    case E_OS_ID:
      PORTA |= SCHM_OS_ID;
      break;
    case E_OS_CALLEVEL:
      PORTA |= SCHM_OS_CALLEVEL;
      break;
    case E_OS_LIMIT:
      PORTA |= SCHM_OS_LIMIT;
      break;
    case E_OS_RESOURCE:
      PORTA |= SCHM_OS_RESOURCE;
      break;
    case E_OS_OK:
    case E_OS_ACCESS:
    case E_OS_NOFUNC:
    case E_OS_STATE:
    case E_OS_VALUE:
    break;
  }
}

/*
** ============================================================================
**     Function    :  vBinaryProgressiveTaskActivation
**
**     Description :
**         Look through all tasks and activate those 
**         whose Mask-Offest match with current counter.
** ============================================================================
*/
void vBinaryProgressiveTaskActivation(void)
{
  UINT8 u8TaskCount = 0;
  tsOS_Task_Cfg const * ptsTask = m_pTasksDescriptor->ptsDescriptor;
  
  if(!boTCMBusy())
  {      
    while(u8TaskCount < m_pTasksDescriptor->u8Task_Number)
    {    
      /* Activation condition */
      if((m_tSchm_Counter & ptsTask->u8Mask) == (ptsTask->u8Mask - ptsTask->u8Offset))
      {
        vUpdateErrorStatus(ActivateTask(ptsTask->tId));
      }
      
      ptsTask++;
      u8TaskCount++;
    }
    boPendingActivation = FALSE;
  }
  else
  {
    boPendingActivation = TRUE;
  }
 }
